package com.ryder.petmatediarybackend.module.shop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ryder.petmatediarybackend.common.exception.BusinessException;
import com.ryder.petmatediarybackend.module.pet.entity.PetProfile;
import com.ryder.petmatediarybackend.module.pet.entity.SysUser;
import com.ryder.petmatediarybackend.module.pet.service.PetProfileService;
import com.ryder.petmatediarybackend.module.pet.service.SysUserService;
import com.ryder.petmatediarybackend.module.shop.dto.CreateAppointmentDTO;
import com.ryder.petmatediarybackend.module.shop.entity.ShopAppointment;
import com.ryder.petmatediarybackend.module.shop.entity.ShopInfo;
import com.ryder.petmatediarybackend.module.shop.mapper.ShopAppointmentMapper;
import com.ryder.petmatediarybackend.module.shop.service.ShopAppointmentService;
import com.ryder.petmatediarybackend.module.shop.service.ShopInfoService;
import com.ryder.petmatediarybackend.module.shop.vo.AppointmentVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 描述: 店铺预约表（疫苗需资质，禁止线上交易）(ShopAppointment)表服务实现类
 * 
 * @author Ryder
 * @version 1.0
 * @since 1.0
 * 更新日期: 2025-10-31
 */
@Slf4j
@Service("shopAppointmentService")
@RequiredArgsConstructor
public class ShopAppointmentServiceImpl extends ServiceImpl<ShopAppointmentMapper, ShopAppointment> implements ShopAppointmentService {

    private final ShopInfoService shopInfoService;
    private final PetProfileService petProfileService;
    private final SysUserService sysUserService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AppointmentVO createAppointment(Long userId, CreateAppointmentDTO dto) {
        log.info("[创建预约] userId={}, shopId={}", userId, dto.getShopId());

        // 验证店铺存在且营业中
        ShopInfo shop = shopInfoService.getById(dto.getShopId());
        if (shop == null) {
            throw new BusinessException("店铺不存在");
        }
        if (shop.getStatus() != 1) {
            throw new BusinessException("店铺未营业");
        }

        // 如果是疫苗预约，检查店铺是否有疫苗资质
        if (dto.getAppointmentType() == 1 && shop.getHasVaccinePermission() != 1) {
            throw new BusinessException("该店铺暂无疫苗服务资质");
        }

        // 验证宠物存在且属于该用户
        PetProfile pet = petProfileService.getById(dto.getPetId());
        if (pet == null || !pet.getUserId().equals(userId)) {
            throw new BusinessException("宠物信息错误");
        }

        // 创建预约
        ShopAppointment appointment = new ShopAppointment();
        BeanUtil.copyProperties(dto, appointment);
        appointment.setUserId(userId);
        appointment.setStatus(0); // 待确认

        boolean saved = this.save(appointment);
        if (!saved) {
            throw new BusinessException("创建预约失败");
        }

        log.info("[创建预约成功] appointmentId={}", appointment.getId());
        return convertToVO(appointment);
    }

    @Override
    public List<AppointmentVO> getMyAppointments(Long userId) {
        log.info("[获取我的预约列表] userId={}", userId);

        LambdaQueryWrapper<ShopAppointment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ShopAppointment::getUserId, userId)
                .orderByDesc(ShopAppointment::getCreateTime);

        List<ShopAppointment> list = this.list(wrapper);
        return list.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelAppointment(Long userId, Long appointmentId, String reason) {
        log.info("[取消预约] userId={}, appointmentId={}", userId, appointmentId);

        ShopAppointment appointment = this.getById(appointmentId);
        if (appointment == null) {
            throw new BusinessException("预约不存在");
        }
        if (!appointment.getUserId().equals(userId)) {
            throw new BusinessException("无权操作");
        }
        if (appointment.getStatus() == 3) {
            throw new BusinessException("预约已取消");
        }
        if (appointment.getStatus() == 2) {
            throw new BusinessException("预约已完成，无法取消");
        }

        appointment.setStatus(3);
        appointment.setCancelTime(LocalDateTime.now());
        appointment.setCancelReason(reason);

        boolean updated = this.updateById(appointment);
        if (!updated) {
            throw new BusinessException("取消预约失败");
        }

        log.info("[取消预约成功] appointmentId={}", appointmentId);
    }

    @Override
    public List<AppointmentVO> getShopAppointments(Long shopId) {
        log.info("[获取店铺预约列表] shopId={}", shopId);

        LambdaQueryWrapper<ShopAppointment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ShopAppointment::getShopId, shopId)
                .orderByDesc(ShopAppointment::getCreateTime);

        List<ShopAppointment> list = this.list(wrapper);
        return list.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirmAppointment(Long shopId, Long appointmentId, String remark) {
        log.info("[确认预约] shopId={}, appointmentId={}", shopId, appointmentId);

        ShopAppointment appointment = this.getById(appointmentId);
        if (appointment == null) {
            throw new BusinessException("预约不存在");
        }
        if (!appointment.getShopId().equals(shopId)) {
            throw new BusinessException("无权操作");
        }
        if (appointment.getStatus() != 0) {
            throw new BusinessException("预约状态错误");
        }

        appointment.setStatus(1);
        appointment.setShopRemark(remark);
        appointment.setConfirmTime(LocalDateTime.now());

        boolean updated = this.updateById(appointment);
        if (!updated) {
            throw new BusinessException("确认预约失败");
        }

        log.info("[确认预约成功] appointmentId={}", appointmentId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void rejectAppointment(Long shopId, Long appointmentId, String reason) {
        log.info("[拒绝预约] shopId={}, appointmentId={}", shopId, appointmentId);

        ShopAppointment appointment = this.getById(appointmentId);
        if (appointment == null) {
            throw new BusinessException("预约不存在");
        }
        if (!appointment.getShopId().equals(shopId)) {
            throw new BusinessException("无权操作");
        }
        if (appointment.getStatus() != 0) {
            throw new BusinessException("预约状态错误");
        }

        appointment.setStatus(4);
        appointment.setShopRemark(reason);

        boolean updated = this.updateById(appointment);
        if (!updated) {
            throw new BusinessException("拒绝预约失败");
        }

        log.info("[拒绝预约成功] appointmentId={}", appointmentId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void completeAppointment(Long shopId, Long appointmentId) {
        log.info("[完成预约] shopId={}, appointmentId={}", shopId, appointmentId);

        ShopAppointment appointment = this.getById(appointmentId);
        if (appointment == null) {
            throw new BusinessException("预约不存在");
        }
        if (!appointment.getShopId().equals(shopId)) {
            throw new BusinessException("无权操作");
        }
        if (appointment.getStatus() != 1) {
            throw new BusinessException("预约状态错误");
        }

        appointment.setStatus(2);
        appointment.setCompleteTime(LocalDateTime.now());

        boolean updated = this.updateById(appointment);
        if (!updated) {
            throw new BusinessException("完成预约失败");
        }

        log.info("[完成预约成功] appointmentId={}", appointmentId);
    }

    /**
     * 转换为VO
     */
    private AppointmentVO convertToVO(ShopAppointment appointment) {
        AppointmentVO vo = new AppointmentVO();
        BeanUtil.copyProperties(appointment, vo);

        // 设置店铺信息
        ShopInfo shop = shopInfoService.getById(appointment.getShopId());
        if (shop != null) {
            vo.setShopName(shop.getShopName());
            vo.setShopAddress(shop.getAddress());
        }

        // 设置用户信息
        SysUser user = sysUserService.getById(appointment.getUserId());
        if (user != null) {
            vo.setUserNickname(user.getNickname());
        }

        // 设置宠物信息
        PetProfile pet = petProfileService.getById(appointment.getPetId());
        if (pet != null) {
            vo.setPetName(pet.getPetName());
        }

        // 设置文本字段
        vo.setAppointmentTypeText(getAppointmentTypeText(appointment.getAppointmentType()));
        vo.setStatusText(getStatusText(appointment.getStatus()));

        return vo;
    }

    /**
     * 获取预约类型文本
     */
    private String getAppointmentTypeText(Integer type) {
        if (type == null) return "未知";
        return switch (type) {
            case 1 -> "疫苗";
            case 2 -> "体检";
            case 3 -> "美容";
            case 4 -> "其他服务";
            default -> "未知";
        };
    }

    /**
     * 获取状态文本
     */
    private String getStatusText(Integer status) {
        if (status == null) return "未知";
        return switch (status) {
            case 0 -> "待确认";
            case 1 -> "已确认";
            case 2 -> "已完成";
            case 3 -> "已取消";
            case 4 -> "已拒绝";
            default -> "未知";
        };
    }
}
